package com.j.lemon.learn.thread.produc1consum;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author lijunjun
 * @Date 2019-04-22 17:29
 * @Description  BlockingQueue 接口实现的生产者消费者模式
 */
public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {
        MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));
        new Thread(()->{
            try{
                myResource.product();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();


        new Thread(()->{
            try{
                myResource.consumer();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();

        TimeUnit.SECONDS.sleep(5);
        myResource.stop();
        System.out.println("关门");

    }
}

class MyResource{
    private BlockingQueue<String> queue = null;

    private volatile boolean flag = true;

    private AtomicInteger atomicInteger = new AtomicInteger();

    public MyResource(BlockingQueue<String> queue) {
        this.queue = queue;
    }

    void product() throws InterruptedException {
        boolean retValue;
        String resource;
        while(flag){
            resource = atomicInteger.incrementAndGet()+"";
            retValue = queue.offer(resource, 1L, TimeUnit.SECONDS);
            if(retValue){
                System.out.println(Thread.currentThread().getName()+"成功生产1个蛋糕");
            }else{
                System.out.println(Thread.currentThread().getName()+"生产蛋糕失败");
            }
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println("停止生产蛋糕");
    }

    void consumer() throws Exception{
        String ret;
        while(flag){
            //如果生产者还没生产蛋糕，则会阻塞2秒
            ret = queue.poll(2L, TimeUnit.SECONDS);
            if(ret==null || "".equalsIgnoreCase(ret)){
                flag = false;
                System.out.println(Thread.currentThread().getName()+"两秒钟没有消费到蛋糕，退出");
                return;
            }
            System.out.println(Thread.currentThread().getName()+"成功消费蛋糕");
        }
    }

    void stop(){
        flag=false;
    }
}
